<?php

namespace SixShop\WechatPay\Trait;

use SixShop\Wechat\Facade\WechatUser;
use SixShop\WechatPay\Facade\WechatPayBuilder;
use think\facade\Log;

trait MiniAppTrait
{

    /**
     * 特殊发货报备
     * @see https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E5%8D%81%E3%80%81%E7%89%B9%E6%AE%8A%E5%8F%91%E8%B4%A7%E6%8A%A5%E5%A4%87
     * @param string $orderID 订单号
     * @param int $type 订单类型 1为预售商品订单，2为测试订单
     * @param int $delayTo 预计发货时间的unix时间戳，type为1时必填，type为2可省略
     */
    private function opSpecialOrder(string $orderID, int $type, int $delayTo = null): bool
    {
        $response = WechatPayBuilder::getMiniApp()->getClient()->postJson('/wxa/sec/order/opspecialorder', [

            'order_id' => $orderID,
            'type' => $type,
            'delay_to' => $delayTo,
        ]);
        $result = json_decode($response->getContent());
        if ($result->errcode != 0) {
            throw new  \InvalidArgumentException($result->errmsg, $result->errcode);
        }
        return true;
    }

    /**
     * 发货信息录入接口
     *
     * @param string $outTradeNo 商户订单号
     * @param int $userID 用户ID
     * @param string $itemDesc 商品描述
     * @param string $trackingNo 物流单号
     * @param string $expressCompany 物流公司编码
     * @param string $receiverContact 收件人联系方式
     * @param bool $failException 是否抛出异常
     * @param int $logisticsType 1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
     *
     * @see https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%80%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3
     * @deprecated 废弃
     */
    private function uploadShippingInfo(
        string $outTradeNo,
        int    $userID,
        string $itemDesc = '',
        string $trackingNo = '',
        string $expressCompany = '',
        string $receiverContact = '',
        int $logisticsType = 1,
        bool   $failException = true,
    ): array
    {
        $data = [
            'order_key' => [
                'order_number_type' => 1, // 枚举值1，使用下单商户号和商户侧单号；枚举值2，使用微信支付单号
                'mchid' => WechatPayBuilder::getConfig()->mchid,
                'out_trade_no' => $outTradeNo,
            ],
            'logistics_type' => $logisticsType, // 物流模式，发货方式枚举值：1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
            'delivery_mode' => 1, // 发货模式，发货模式枚举值：1、UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货） 示例值: UNIFIED_DELIVERY
            'upload_time' => date('c'), // 上传时间，用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00`
            'payer' => [
                'openid' => WechatUser::openid($userID), // 用户标识，用户在小程序appid下的唯一标识
            ]
        ];
        if ($logisticsType == 1) {
            $data['shipping_list'] = [
                [
                    'tracking_no' => $trackingNo, // 物流单号
                    'express_company' => $expressCompany, // 物流公司编码，快递公司ID
                    'item_desc' => $itemDesc,
                    'contact' => [
                        'receiver_contact' => substr_replace($receiverContact, '****', -8, 4), // 收件人联系方式
                    ],
                ],
            ];
        } else {
            $data['shipping_list'] = [
                [
                    'item_desc' => $itemDesc,
                ],
            ];
        }
        $response = WechatPayBuilder::getMiniApp()->getClient()->postJson('wxa/sec/order/upload_shipping_info', $data);
        $result = $response->getContent();
        $result = json_decode($result, true);
        if ($result['errcode'] !== 0) {
            Log::error('更新发货信息失败{errcode}:{errmsg}:' . json_encode($data), $result);
            $failException && throw new \RuntimeException($result['errmsg'], $result['errcode']);
        }
        return $result;
    }

    /**
     * 传运单接口 trace_waybill
     *
     * @see https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_search.html
     */
    private function waybillToken(
        int $userID,
        string $receiverPhone,
        string $waybillID,
        string $deliveryID,
        array $detailList,
        bool   $failException = true
    ): array
    {
        // POST https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/trace_waybill?access_token=XXX
        $data = [
            'openid' => WechatUser::openid($userID),
            'receiver_phone' => $receiverPhone,
            'waybill_id' => $waybillID,
            'delivery_id' => $deliveryID,
            'detail_list' => $detailList,
            'goods_info' => [
                'detail_list' => $detailList
            ],
        ];
        $response = WechatPayBuilder::getMiniApp()->getClient()->postJson('cgi-bin/express/delivery/open_msg/trace_waybill', $data);
        $result = $response->getContent();
        $result = json_decode($result, true);
        if ($result['errcode'] !== 0) {
            Log::error('获取运单token失败{errcode}:{errmsg}:' . json_encode($data), $result);
            $failException && throw new \RuntimeException($result['errmsg'], $result['errcode']);
        }
        return $result;
    }
}